package com.lancoo.cvas.arrangecourse.entities;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.LinkedList;
import java.util.List;

/**
 * @Description 排课教学班单元
 * @Author Fortysun
 * @Date 2023/5/16 16:41
 **/
@Data
@NoArgsConstructor
public class TeachingClassUnit implements Comparable<TeachingClassUnit> {
    public TeachingClassUnit(TeachingClassUnit cloneable) {
        teachingClassUnitId = cloneable.getTeachingClassUnitId();
        teachingClassId = cloneable.getTeachingClassId();
        teachingClassName = cloneable.getTeachingClassName();
        teachingClassType = cloneable.getTeachingClassType();
        teachingClassSize = cloneable.getTeachingClassSize();
        teacherIds = cloneable.getTeacherIds();
        studentIds = cloneable.getStudentIds();
        classWeeks = cloneable.getClassWeeks();
        roomType = cloneable.getRoomType();
        courseType = cloneable.getCourseType();
        teachingType = cloneable.getTeachingType();
        taskId = cloneable.getTaskId();
        prohibitTimeslotCodes = cloneable.getProhibitTimeslotCodes();
        courseId = cloneable.getCourseId();
        courseName = cloneable.getCourseName();
        campusId = cloneable.getCampusId();
        connectSection = cloneable.getConnectSection();
        connectNumber = cloneable.getConnectNumber();
        fixTimeslotCodes = cloneable.getFixTimeslotCodes();
        roomId = cloneable.getRoomId();
        subTeachingClassId = cloneable.getSubTeachingClassId();
        timeslotRoomList = cloneable.getTimeslotRoomList();
        uniqueShiftSign = cloneable.getUniqueShiftSign();
        phyClassId = cloneable.getPhyClassId();
        splitClassGroupId = cloneable.getSplitClassGroupId();
        isSingle = cloneable.getIsSingle();
        courseTeacherIDs = cloneable.getCourseTeacherIDs();
    }

    //教学班排课单元id
    private Integer teachingClassUnitId;

    //教学班id
    private Long teachingClassId;

    //教学班名称
    private String teachingClassName;

    /**
     * 教学班类型 0:无需选课 1:在线选课 2:分级教学 3:预选教学班
     */
    private Integer teachingClassType;

    //教学班人数
    private Integer teachingClassSize;

    //教师id字符串，多个教师以逗号分隔
    private String teacherIds;

    //教学班的所有学生id，没有默认为空,多个用逗号分隔
    private String studentIds;

    //上课周次，二进制表示，一个学期有多少周，就有多少位，有课为1，无课为0
    //如单双周，就是101010...，这种样式
    private String classWeeks;

    //教室类型
    private Integer roomType;

    //课程属性，是环节还是课程，课程1，环节2；
    private Integer courseType;

    //授课类型，讲授1，实验2，上机3，其他4；
    private Integer teachingType;

    //学期排课计划id
    private Integer taskId;

    //禁排的上课课时；
    private String prohibitTimeslotCodes;

    //课程id
    private Long courseId;

    //课程名称
    private String courseName;

    //校区id
    private String campusId;

    //连上节次
    private Integer connectSection;

    //连上次数
    private Integer connectNumber;
    private String timeGroup;

    //排课安排的教室课时分组信息列表
    private LinkedList<TimeslotRoom> timeslotRoomList;

    //尽量排的课时，主要用于尽量排规则中，处理指定教学班的教室课时分组信息
    //存储规则，0101、0301分别代表周一第1节、周三第1节
    private List<String> fixTimeslotCodes;
    //教学班指定分配的教室的id，
    //如果是需要拆班的教学班，教室id会存在多个，以逗号进行分隔
    private String roomId;

    /**
     * 子教学班id
     */
    private Integer subTeachingClassId;
    //行政班id
    private String phyClassId;
    /**
     * 分班标识 UUID生成 相同分组的教学班，标识相同，排课时需要分配相同课时的教学班
     */
    private String uniqueShiftSign;
    //拆班分组的id，标识哪两节课需要分配相同的课时,UUID生成
    private String splitClassGroupId;
    /**
     * 拆班学生分配 1单数 2双数
     */
    private Integer isSingle;
    //课程+教师id字符串，用于拆班课程的区分
    //由于有些课程，需要两个教师教，通过这种方式，来区分不同的课程对应的教学班
    private String courseTeacherIDs;


    @Override
    public int compareTo(TeachingClassUnit o) {
        //按教学班人数升序
        if (o.getTeachingClassSize() < this.getTeachingClassSize()) {
            return 1;
        } else if (o.getTeachingClassSize() > this.getTeachingClassSize()) {
            return -1;
        }
        //如果教学班人数相等，则按照连上节次降序
        if (o.getConnectSection() < this.getConnectSection()) {
            return -1;
        } else if (o.getConnectSection() > this.getConnectSection()) {
            return 1;
        }

        return 0;
    }

    public int getRuleNum() {
        List<String> fixTimeslotCodes = this.getFixTimeslotCodes();
        String prohibitTimeslotCodes = this.getProhibitTimeslotCodes();
        String roomId = this.getRoomId();
        int fixSize = CollUtil.isNotEmpty(fixTimeslotCodes) ? fixTimeslotCodes.size() : 0;
        int prohibitSize = StrUtil.isNotEmpty(prohibitTimeslotCodes) ? prohibitTimeslotCodes.split(",").length : 0;
        int roomSize = StrUtil.isNotEmpty(roomId) ? 1 : 0;
        return fixSize + prohibitSize + roomSize;
    }
}
